/**
 * 模拟记忆操作器 - 仅用于测试
 */

import { MemoryOperator } from '../../message-broker';

interface MockMemoryItem {
  id: string;
  content: string;
  operation: string;
  timestamp: Date;
  metadata?: Record<string, any>;
}

export class MockMemoryOperator implements MemoryOperator {
  private memories: Map<string, MockMemoryItem> = new Map();
  private operationDelay: number;
  private shouldFail: boolean;
  private operationHistory: Array<{
    operation: string;
    data: any;
    timestamp: Date;
    success: boolean;
  }> = [];

  constructor(options: {
    operationDelay?: number;
    shouldFail?: boolean;
  } = {}) {
    this.operationDelay = options.operationDelay ?? 100;
    this.shouldFail = options.shouldFail ?? false;
  }

  async handleMemoryOperation(
    operation: 'save' | 'retrieve' | 'update' | 'delete',
    data: any,
    options: any
  ): Promise<any> {
    const startTime = Date.now();
    
    // 记录操作历史
    const historyEntry = {
      operation,
      data,
      timestamp: new Date(),
      success: false
    };

    try {
      // 模拟操作延迟
      await this.delay(this.operationDelay);

      if (this.shouldFail) {
        throw new Error(`Mock memory operation ${operation} failed`);
      }

      let result: any;

      switch (operation) {
        case 'save':
          result = await this.handleSave(data);
          break;
        case 'retrieve':
          result = await this.handleRetrieve(data);
          break;
        case 'update':
          result = await this.handleUpdate(data);
          break;
        case 'delete':
          result = await this.handleDelete(data);
          break;
        default:
          throw new Error(`Unknown memory operation: ${operation}`);
      }

      historyEntry.success = true;
      this.operationHistory.push(historyEntry);

      return {
        success: true,
        operation,
        result,
        metadata: {
          executionTime: Date.now() - startTime,
          timestamp: new Date(),
          mock: true
        }
      };

    } catch (error) {
      this.operationHistory.push(historyEntry);
      
      return {
        success: false,
        operation,
        error: error instanceof Error ? error.message : String(error),
        metadata: {
          executionTime: Date.now() - startTime,
          timestamp: new Date(),
          mock: true
        }
      };
    }
  }

  private async handleSave(data: any): Promise<any> {
    const id = this.generateId();
    const memory: MockMemoryItem = {
      id,
      content: data.content || String(data),
      operation: 'save',
      timestamp: new Date(),
      metadata: { ...data.metadata, mock: true }
    };

    this.memories.set(id, memory);

    return {
      id,
      content: memory.content,
      status: 'saved',
      mock: true
    };
  }

  private async handleRetrieve(data: any): Promise<any> {
    const { query, limit = 10 } = data;
    
    // 简单的模拟检索 - 基于内容匹配
    const results: MockMemoryItem[] = [];
    
    for (const memory of this.memories.values()) {
      if (!query || memory.content.toLowerCase().includes(query.toLowerCase())) {
        results.push(memory);
        if (results.length >= limit) break;
      }
    }

    return {
      memories: results,
      total: results.length,
      query,
      mock: true
    };
  }

  private async handleUpdate(data: any): Promise<any> {
    const { id, content, metadata } = data;
    
    const existing = this.memories.get(id);
    if (!existing) {
      throw new Error(`Memory with id ${id} not found`);
    }

    const updated: MockMemoryItem = {
      ...existing,
      content: content || existing.content,
      metadata: { ...existing.metadata, ...metadata, mock: true },
      timestamp: new Date()
    };

    this.memories.set(id, updated);

    return {
      id,
      content: updated.content,
      status: 'updated',
      mock: true
    };
  }

  private async handleDelete(data: any): Promise<any> {
    const { id } = data;
    
    const deleted = this.memories.delete(id);
    
    if (!deleted) {
      throw new Error(`Memory with id ${id} not found`);
    }

    return {
      id,
      status: 'deleted',
      mock: true
    };
  }

  // 测试辅助方法
  setShouldFail(shouldFail: boolean): void {
    this.shouldFail = shouldFail;
  }

  setOperationDelay(delay: number): void {
    this.operationDelay = delay;
  }

  getMemoryCount(): number {
    return this.memories.size;
  }

  getAllMemories(): MockMemoryItem[] {
    return Array.from(this.memories.values());
  }

  clearAllMemories(): void {
    this.memories.clear();
  }

  getOperationHistory(): typeof this.operationHistory {
    return [...this.operationHistory];
  }

  clearOperationHistory(): void {
    this.operationHistory = [];
  }

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  private generateId(): string {
    return `mock_mem_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
  }
}
